package com.uid.service.impl;

import com.uid.model.UniqueIdSequence;
import com.uid.dao.IUniqueIdSequenceDao;
import com.uid.service.IUniqueIdSequenceService;
import com.xr.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;

import java.util.concurrent.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Arnold Yang
 * @since 2018-02-21
 */
@Service
public class UniqueIdSequenceServiceImpl extends BaseServiceImpl<IUniqueIdSequenceDao, UniqueIdSequence> implements IUniqueIdSequenceService {

  private final ConcurrentHashMap<Integer, ArrayBlockingQueue<Long>> typeMap = new ConcurrentHashMap<>();
  private final ExecutorService threadpool = Executors.newFixedThreadPool(3);

  @Override
  public long replaceInto(UniqueIdSequence uid) throws Exception {
    this.baseMapper.replaceInto(uid);
    return uid.getId();
  }

  @Override
  public long nextId(int stub) throws Exception {
    Integer type = Integer.valueOf(stub);
    checkType(type);
    checkBlockingQueue(type);
    return typeMap.get(type).take();
  }

  private void checkType(Integer type){
    if( this.typeMap.containsKey(type) ){
      return;
    }

    // init type
    typeMap.put(type, new ArrayBlockingQueue(2000));
  }

  private void checkBlockingQueue(Integer type){
    ArrayBlockingQueue<Long> abq = typeMap.get(type);
    if(abq.isEmpty()){
      threadpool.submit(new Runnable() {
        @Override
        public void run() {
          while (true) {
            try {
              UniqueIdSequence idm = new UniqueIdSequence(0L, type);
              baseMapper.replaceInto(idm);
              abq.add(idm.getId());
            } catch (Exception e){
              break;
            }
          }
        }
      });
    }
  }

}
